package cn.iocoder.yudao.module.signature.validatap12status.cermb;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.security.Security;

/**
 * 苹果证书验证器
 * 用于验证p12证书和描述文件是否匹配
 */
public class AppleCertificateValidator {
    
    private static final Logger logger = LoggerFactory.getLogger(AppleCertificateValidator.class);
    
    // 添加BouncyCastle安全提供者
    static {
        Security.addProvider(new BouncyCastleProvider());
    }
    
    /**
     * 验证结果类
     */
    public static class ValidationResult {
        private boolean valid;
        private String message;
        private java.util.Map<String, String> details;
        
        public ValidationResult(boolean valid, String message) {
            this.valid = valid;
            this.message = message;
            this.details = new java.util.HashMap<>();
        }
        
        public boolean isValid() {
            return valid;
        }
        
        public void setValid(boolean valid) {
            this.valid = valid;
        }
        
        public String getMessage() {
            return message;
        }
        
        public void setMessage(String message) {
            this.message = message;
        }
        
        public java.util.Map<String, String> getDetails() {
            return details;
        }
        
        public void addDetail(String key, String value) {
            details.put(key, value);
        }
        
        @Override
        public String toString() {
            return "ValidationResult{" +
                    "valid=" + valid +
                    ", message='" + message + '\'' +
                    ", details=" + details +
                    '}';
        }
    }
    
    /**
     * 验证p12证书和描述文件是否匹配
     * 
     * @param p12FilePath p12证书文件路径
     * @param p12Password p12证书密码
     * @param provisioningProfilePath 描述文件路径
     * @return 验证结果
     */
    public ValidationResult validateCertificateAndProfile(String p12FilePath, String p12Password, 
                                                         String provisioningProfilePath) {
        try {
            logger.info("开始验证证书和描述文件匹配性");
            
            // 1. 加载p12证书
            java.security.KeyStore p12KeyStore = CertificateUtils.loadP12Certificate(p12FilePath, p12Password);
            if (p12KeyStore == null) {
                return new ValidationResult(false, "无法加载p12证书文件");
            }
            
            // 2. 提取证书信息
            CertificateInfo certInfo = CertificateUtils.extractCertificateInfo(p12KeyStore);
            if (certInfo == null) {
                return new ValidationResult(false, "无法提取证书信息");
            }
            
            // 3. 解析描述文件
            ProvisioningProfileInfo profileInfo = ProvisioningProfileUtils.parseProvisioningProfile(provisioningProfilePath);
            if (profileInfo == null) {
                return new ValidationResult(false, "无法解析描述文件");
            }
            
            // 4. 验证匹配性
            return validateMatch(certInfo, profileInfo);
            
        } catch (Exception e) {
            logger.error("验证过程中发生错误", e);
            return new ValidationResult(false, "验证失败: " + e.getMessage());
        }
    }
    
    /**
     * 验证证书和描述文件是否匹配
     */
    private ValidationResult validateMatch(CertificateInfo certInfo, ProvisioningProfileInfo profileInfo) {
        ValidationResult result = new ValidationResult(true, "验证通过");
        
        // 1. 验证证书指纹是否在描述文件中
        boolean fingerprintMatch = ProvisioningProfileUtils.isCertificateFingerprintInProfile(
            certInfo.getFingerprint(), profileInfo);
        
        if (!fingerprintMatch) {
            result.setValid(false);
            result.setMessage("证书指纹不匹配");
            result.addDetail("证书指纹", certInfo.getFingerprint());
            if (profileInfo.getCertificateFingerprints() != null) {
                result.addDetail("描述文件中的指纹", String.join(", ", profileInfo.getCertificateFingerprints()));
            } else {
                result.addDetail("描述文件中的指纹", "无");
            }
            return result;
        }
        
        // 2. 验证证书有效期
        if (!CertificateUtils.isCertificateValid(certInfo)) {
            long currentTime = System.currentTimeMillis();
            if (certInfo.getNotAfter().getTime() < currentTime) {
                result.setValid(false);
                result.setMessage("证书已过期");
                result.addDetail("证书过期时间", certInfo.getNotAfter().toString());
                return result;
            }
            
            if (certInfo.getNotBefore().getTime() > currentTime) {
                result.setValid(false);
                result.setMessage("证书尚未生效");
                result.addDetail("证书生效时间", certInfo.getNotBefore().toString());
                return result;
            }
        }
        
        // 3. 验证Team ID
        String certTeamId = CertificateUtils.extractTeamIdFromSubject(certInfo.getSubjectDN());
        if (certTeamId != null && profileInfo.getTeamIdentifier() != null) {
            if (!ProvisioningProfileUtils.isTeamIdMatch(certTeamId, profileInfo)) {
                result.setValid(false);
                result.setMessage("Team ID不匹配");
                result.addDetail("证书Team ID", certTeamId);
                result.addDetail("描述文件Team ID", profileInfo.getTeamIdentifier());
                return result;
            }
        }
        
        // 4. 添加详细信息
        result.addDetail("证书类型", certInfo.getCertificateType());
        result.addDetail("证书主题", certInfo.getSubjectDN());
        result.addDetail("证书序列号", certInfo.getSerialNumber());
        result.addDetail("描述文件UUID", profileInfo.getUuid());
        result.addDetail("描述文件名称", profileInfo.getName());
        result.addDetail("App ID名称", profileInfo.getAppIdName());
        
        logger.info("证书和描述文件验证通过");
        return result;
    }
} 